local DisplayBlock = {} 

DisplayBlock.__index = DisplayBlock

setmetatable(DisplayBlock, {
	__call = function (cls, ...)
		return cls.new(...)
	end,
})

function DisplayBlock.new(xmlDoc)
	local self = setmetatable({}, DisplayBlock)

	self.xmlDoc = xmlDoc
	self.content = { }
	self.ContentFrame = Apollo.LoadForm(self.xmlDoc, "ContentFrame", nil, self)
	self.ContentList = self.ContentFrame:FindChild("ContentList")
	self.contentSoundNew = nil
	self.contentSoundEnds = nil
	self.notifyTime = 2

	self.bgColor = CColor.new(0,0,0,1)
	self.barColor = CColor.new(1,0,0,0.5)
	self.isEnabled = true
	self.anchorFromTop = true
	self.barSize = {
		Width = 300,
		Height = 28
	}

	return self
end

----------------------
-- SAVE AND RESTORE --
----------------------
function DisplayBlock:Load(saveData)
	if saveData.bgColor ~= nil then
		self:SetBGColor(CColor.new(saveData.bgColor[1], saveData.bgColor[2], saveData.bgColor[3], saveData.bgColor[4]))
	end

	if saveData.barColor ~= nil then
		self:SetBarColor(CColor.new(saveData.barColor[1], saveData.barColor[2], saveData.barColor[3], saveData.barColor[4]))
	end

	if saveData.isEnabled ~= nil then
		self:SetEnabled(saveData.isEnabled)
	end

	if saveData.barSize ~= nil then
		self.barSize = saveData.barSize
	end

	if saveData.Position ~= nil then
		self.ContentFrame:SetAnchorOffsets(saveData.Position[1], saveData.Position[2], saveData.Position[1] + self.barSize.Width, saveData.Position[2] + self.ContentFrame:GetHeight())
	end

	if saveData.anchorFromTop ~= nil then
		self.anchorFromTop = saveData.anchorFromTop
	end
end

function DisplayBlock:GetSaveData()
	local left, top, right, bottom = self.ContentFrame:GetAnchorOffsets()
	local saveData = {
		bgColor = { self.bgColor.r, self.bgColor.g, self.bgColor.b, self.bgColor.a },
		barColor = { self.barColor.r, self.barColor.g, self.barColor.b, self.barColor.a },
		isEnabled = self.isEnabled,
		Position = { left, top },
		anchorFromTop = self.anchorFromTop,
		barSize = self.barSize,
	}
	return saveData
end
-----------------------
-- /SAVE AND RESTORE --
-----------------------

--------------------
-- GUI MANAGEMENT --
--------------------
function DisplayBlock:SetName(name)
	self.ContentFrame:FindChild("MoveAnchor"):SetText(name)
end

function DisplayBlock:SetPosition(x, y)
	self.ContentFrame:SetAnchorPoints(x, y, x, y)
end

function DisplayBlock:ResetPosition()
	self.ContentFrame:SetAnchorOffsets(-150, -200, 150, 200)
	self:SetBarWidth(self.barSize.Width)
	if not self.anchorFromTop then
		self:AnchorFromTop(false, true)
	end
end

local function SortContentByTime(a, b)
	return a:GetData().remains < b:GetData().remains
end

function DisplayBlock:SetEnabled(isEnabled)
	self.isEnabled = isEnabled
	if not isEnabled then
		for _, bar in pairs(self.content) do
			self.content[bar.text] = nil
			bar.Frame:Destroy()
			self.ContentList:ArrangeChildrenVert(self:GetAnchorPoint(), SortContentByTime)
		end
	end
end

function DisplayBlock:IsEnabled()
	return self.isEnabled
end

function DisplayBlock:SetMovable(isMovable)
	self.ContentFrame:FindChild("MoveAnchor"):Show(isMovable)
	self.ContentFrame:SetStyle("Picture", isMovable)
	self.ContentFrame:SetStyle("Moveable", isMovable)
end

function DisplayBlock:SetBarWidth(width)
	local left, top, right, bottom = self.ContentFrame:GetAnchorOffsets()
	right = left + width
	self.ContentFrame:SetAnchorOffsets(left, top, right, bottom)
	self.barSize.Width = width
end

function DisplayBlock:SetBarHeight(height)
	self.barSize.Height = height
	for _, bar in pairs(self.content) do
		bar:SetHeight(height)
	end
	self.ContentList:ArrangeChildrenVert(self:GetAnchorPoint(), SortContentByTime)
end

function DisplayBlock:ClearAll()
	for _, bar in pairs(self.content) do
		self.content[bar.text] = nil
		bar.Frame:Destroy()
	end
	self.ContentList:ArrangeChildrenVert(self:GetAnchorPoint(), SortContentByTime)
end

function DisplayBlock:SetBGColor(color)
	self.bgColor = color
	for _, bar in pairs(self.content) do
		bar:SetBGColor(color)
	end
end

function DisplayBlock:SetBarColor(color)
	self.barColor = color
	for _, bar in pairs(self.content) do
		bar:SetBarColor(color)
	end
end

function DisplayBlock:AnchorFromTop(anchorTop, force)
	if self.anchorFromTop ~= anchorTop or force then
		self.anchorFromTop = anchorTop
		local left, top, right, bottom = self.ContentFrame:GetAnchorOffsets()
		if anchorTop then
			self.ContentFrame:SetAnchorOffsets(left, top + self.ContentFrame:GetHeight(), right, top + self.ContentFrame:GetHeight() + self.ContentFrame:GetHeight())
		else
			self.ContentFrame:SetAnchorOffsets(left, top - self.ContentFrame:GetHeight(), right, top - self.ContentFrame:GetHeight() + self.ContentFrame:GetHeight())
		end
		self.ContentList:ArrangeChildrenVert(self:GetAnchorPoint(), SortContentByTime)
	end
end

function DisplayBlock:GetAnchorPoint()
	return self.anchorFromTop and Window.CodeEnumArrangeOrigin.LeftOrTop or Window.CodeEnumArrangeOrigin.RightOrBottom
end
---------------------
-- /GUI MANAGEMENT --
---------------------

----------------------
-- BLOCK MANAGEMENT --
----------------------
function DisplayBlock:ProcessTimers()
	if self.isEnabled then
		for _, bar in pairs(self.content) do
			self:ProcessTimer(bar)
		end
	end
end

function DisplayBlock:ProcessTimer(bar)
	local currTime = GameLib.GetGameTime()
	local timeRemaining = bar.EndTime - currTime
	if not bar.notified and timeRemaining < self.notifyTime then
		Sound.PlayFile(self.contentSoundEnds)
		bar.notified = true
	end
	if bar.destroyAtEnd then
		if timeRemaining < 0 then
			self.content[bar.text] = nil
			bar.Frame:Destroy()
			self.ContentList:ArrangeChildrenVert(self:GetAnchorPoint(), SortContentByTime)
		else
			bar:SetTimer(timeRemaining)
		end
	else
		bar:SetTimer(timeRemaining)
	end
end

function DisplayBlock:AddTimer(msg)
	local timerBar = self.content[msg.text]
	if timerBar == nil then
		timerBar = self:CreateBar(msg)
		self.content[msg.text] = timerBar
		local frameData = {remains = msg.maxtime}
		timerBar.Frame:SetData(frameData)
		self.ContentList:ArrangeChildrenVert(self:GetAnchorPoint(), SortContentByTime)
	else
		self.content[msg.text] = nil
		timerBar.Frame:Destroy()
		timerBar = self:CreateBar(msg)
		self.content[msg.text] = timerBar
		local frameData = {remains = msg.maxtime}
		timerBar.Frame:SetData(frameData)
		self.ContentList:ArrangeChildrenVert(self:GetAnchorPoint(), SortContentByTime)
	end
	Sound.PlayFile(self.contentSoundNew)
end

function DisplayBlock:CreateBar(msg)
	local bar = RaiderinoLibs.DisplayBar.new(self.xmlDoc, self, msg)
	bar:SetBGColor(self.bgColor)
	bar:SetBarColor(self.barColor)
	bar:SetHeight(self.barSize.Height)
	return bar
end
-----------------------
-- /BLOCK MANAGEMENT --
-----------------------

if _G["RaiderinoLibs"] == nil then
	_G["RaiderinoLibs"] = { }
end
_G["RaiderinoLibs"]["DisplayBlock"] = DisplayBlock